home *** CD-ROM | disk | FTP | other *** search
Wrap
/* Copyright, 1990, Regents of the University of Colorado */ #define BOOL char #define TRUE 1 #define FALSE 0 #define MAXINCLUDE 11 #define MAXMACHINES 10 #define MAXMACHNAME 20 #define MAXDIM 50 #define OPTIONSIZE 50 #define LINESIZE 256 #define NAMESIZE 15 #include <stdio.h> #include <string.h> #include <varargs.h> #include <sys/types.h> #include <sys/param.h> #include <sys/stat.h> #include <pwd.h> #include <ctype.h> #include "../inc/version.h" static BOOL numcheck(); static void error(); static void message(); static void dmessage(); static void cmdlnparse(); static void addbools(); static void sh_message(); static BOOL QUIET = FALSE; static BOOL ALADIN = FALSE; static BOOL COMMENTS = FALSE; static BOOL ORDER = FALSE; static BOOL NUMBERS = FALSE; static BOOL NOTES = FALSE; static BOOL WARNINGS = FALSE; static BOOL SUFFIX_MODEL = TRUE; static BOOL header = FALSE; static BOOL MODEL = FALSE; static char TYPE; static char SERIES; static char DIRECTORY[MAXPATHLEN] = {0}; static char SUFFIX[25] = {0}; static char INCLUDE[MAXINCLUDE][MAXPATHLEN]; static char SOURCE[MAXPATHLEN] = {0}; static char USER[NAMESIZE] = {0}; static int NINC = 0; static int CUBEDIM = 0; static long int BUFSIZE = 0; static long int LASTTYPE = 0; static long int FIRSTTYPE = 0; static int PARTIAL = 3; static struct { char name[MAXMACHNAME]; char suffix[MAXMACHNAME + 2]; char address[MAXPATHLEN]; char user[NAMESIZE]; char directory[MAXPATHLEN]; char rdirectory[MAXPATHLEN]; int type; int maxdim; int dim; BOOL rcp; BOOL rsh; char run; BOOL date; BOOL lcl_here; } machines[MAXMACHINES]; static int nummach = 0; static int default_mach = 0; static BOOL macherr = FALSE; extern void exit(); extern long int strtol(); extern char *getenv(); main(argc, argv) int argc; char *argv[]; { char ROOT[MAXPATHLEN]; int I, J, K, L, M; char cmdln[OPTIONSIZE]; char *temp, *temp2, *home; int test; char varname[MAXMACHNAME + 6]; char username[25]; BOOL used; BOOL special = FALSE; char tempdir[MAXPATHLEN]; char OUTLINE[LINESIZE]; int mask; struct stat buf1; struct passwd *pwbuf; /* Get the default environment parameters (These are set in the script that calls this program.) */ /* The first of these is the list of machines that are defined on this system. These (and their characteristics) should be defined in the environment variable "Dmachs". */ if ((temp = getenv("Dmachs")) == NULL) { /* If there is no such variable, set the following default parameters: */ macherr = TRUE; PARTIAL = 0; MODEL = TRUE; TYPE = 'c'; SERIES = '2'; CUBEDIM = 4; } else { /* Otherwise, check to see if Dmachs is empty: */ if (temp[0] == '\0') error(1, "\tEmpty Dmachs environment string found.\n\n"); J = 0; for (I = 0; I < MAXMACHINES; I++) { /* If it is not, for each machine defined in the variable: */ /* Read the name. */ for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) machines[I].name[K] = temp[J]; machines[I].name[K] = '\0'; /* Read the address. */ for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) machines[I].address[K] = temp[J]; machines[I].address[K] = '\0'; /* Read the user code. */ for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) machines[I].user[K] = temp[J]; machines[I].user[K] = '\0'; /* Read the directory code. */ for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) machines[I].directory[K] = temp[J]; machines[I].directory[K] = '\0'; /* Get the machine type and check that it is correct. */ for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); switch (temp[J++]) { case 's' : machines[I].type = 5; break; case 'S' : machines[I].type = 6; break; case '1' : machines[I].type = 1; break; case '2' : machines[I].type = 2; break; case '8' : machines[I].type = 3; break; case 'G' : machines[I].type = 4; break; default: error(0, "\tInvalid machine type for %s in Dmachs.\n", machines[I].name); } /* Get the maximum number of dimensions for this machine and check this against the defined maximum. */ if ((machines[I].maxdim = (int) strtol(&(temp[J++]), (char **) NULL, 0)) < 1 || machines[I].maxdim > MAXDIM) error(0, "\tInvalid max dimension (%d) for %s in Dmachs.\n", machines[I].maxdim, machines[I].name); /* Get the value of the Rcp switch and check it for validity. */ for (; isdigit(temp[J]); J++); switch (temp[J++]) { case 'T' : machines[I].rcp = TRUE; break; case 'F' : machines[I].rcp = FALSE; break; default: error(0, "\tInvalid remote copy option for %s in Dmachs.\n", machines[I].name); } /* Get the value of the Rsh switch and check it for validity. */ switch (temp[J++]) { case 'T' : machines[I].rsh = TRUE; break; case 'F' : machines[I].rsh = FALSE; break; default: error(0, "\tInvalid dino2 option for %s in Dmachs.\n", machines[I].name); } /* Get the value of the Run switch and check it for validity. */ switch (temp[J++]) { case 'T' : machines[I].run = 'T'; break; case 'F' : machines[I].run = 'F'; break; case 'S' : machines[I].run = 'S'; break; default: error(0, "\tInvalid execution option for %s in Dmachs.\n", machines[I].name); } /* Get the value of the Date switch and check it for validity. */ switch (temp[J++]) { case 'T' : machines[I].date = TRUE; break; case 'F' : machines[I].date = FALSE; break; default: error(0, "\tInvalid remote copy option for %s in Dmachs.\n", machines[I].name); } /* Get the default number of dimensions and check that for validity. */ if ((machines[I].dim = (int) strtol(&(temp[J++]), (char **) NULL, 0)) < 1 || machines[I].dim > machines[I].maxdim) error(0, "\tInvalid default dimension (%d) for %s in Dmachs.\n", machines[I].dim, machines[I].name); /* Do some clean-up at the end of the descriptor for this machine. */ for (; isdigit(temp[J]); J++); nummach++; if (temp[J] != ' ' && temp[J] != '\t' && temp[J] != '\0' && temp[J] != '\n') error(0, "\tInvalid descriptor for %s in Dmachs.\n", machines[I].name); /* Now, we will check that the descriptors for this machine are consistant with each other (OK, we will also do some processing so we can use the information later): */ if (machines[I].address[0] == '.') { /* Insure that an address of "." has no additional characters. */ if (machines[I].run == 'T' && machines[I].address[1] != '\0') error(0, "\tInvalid address (%s) for %s in Dmachs.\n", machines[I].address, machines[I].name); /* Check to see that there is not a local address then an "rcp" to copy files. */ if (machines[I].run == 'T' && machines[I].rcp) error(0, "\tAddress (.) for %s in Dmachs is inconsistant with rcp option.\n", machines[I].name); /* Check to see that there is not a local address then an "rsh" to execute the backend of the compiler. */ if (machines[I].run == 'T' && machines[I].rsh) error(0, "\tAddress (.) for %s in Dmachs is inconsistant with rsh option.\n", machines[I].name); } else /* Check to see that there is not a remote address then no "rsh" to execute the backend of the compiler. */ if (machines[I].run == 'T' && ! machines[I].rsh) error(0, "\tAddress (%s) for %s in Dmachs is inconsistant with rsh option.\n\t\tA local machine must have an address of \".\"\n", machines[I].address, machines[I].name); if (machines[I].user[0] == '~') { /* Insure that an user of "~" has no additional characters. */ if (machines[I].user[1] != '\0') error(0, "\tInvalid user (%s) for %s in Dmachs.\n", machines[I].user, machines[I].name); } else { /* Insure that the user is not ".". */ if (machines[I].user[0] == '.') error(0, "\tInvalid user (%s) for %s in Dmachs.\n", machines[I].user, machines[I].name); /* Check to see that if this is not a remote machine then the user for the back end is the current user. */ if (machines[I].run == 'T' && ! machines[I].rsh) error(0, "\tInvalid user (%s) for %s in Dmachs on local machine\n", machines[I].user, machines[I].name); } machines[I].lcl_here = FALSE; switch (machines[I].directory[0]) { case '.': /* Check to see if this is a remote machine that requires an "rcp" to get the files there, that the default directory for the remote machine is not the current directory. */ if (machines[I].run == 'T' && machines[I].rcp) error(0, "\tInvalid directory (%s) for remote machine %s in Dmachs.\n", machines[I].directory, machines[I].name); /* If the current directory is the default, put in the actual name of the directory instead of "." */ (void) strcpy(tempdir, machines[I].directory); (void) strcpy(machines[I].directory, getenv("PWD")); if (tempdir[1] != '\0') { /* If there is more than just ".", make sure it is a sub-directory. */ if (tempdir[1] != '/') error(0, "\tInvalid directory (%s) for remote machine %s in Dmachs.\n", machines[I].directory, machines[I].name); (void) strcat(machines[I].directory, &(tempdir[1])); } else /* If it is actually this directory, set a flag so we know that later. */ machines[I].lcl_here = TRUE; /* If we are going to execute on a remote machine, construct an abbreviated directory name for it. */ if (machines[I].rsh) { home = getenv("HOME"); for (L = 0; home[L] != '\0' && home[L] == machines[I].directory[L]; L++); M = 0; if (machines[I].directory[L] != '\0') for (L++; machines[I].directory[L] != '\0'; L++, M++) machines[I].rdirectory[M] = machines[I].directory[L]; machines[I].rdirectory[M] = '\0'; } break; case '~': if (machines[I].run == 'T') { if (machines[I].rcp) { /* If we use an "rcp" to get the files to the remote machine, strip the "~" or "~/" out. */ if (machines[I].directory[1] == '\0') machines[I].directory[0] = '\0'; else if (machines[I].directory[1] == '/') for (L = 0; machines[I].directory[L] != '\0'; L++) machines[I].directory[L] = machines[I].directory[L+2]; strcpy(machines[I].rdirectory, machines[I].directory); } else { /* If we don't use an "rcp": */ /* If we do use an "rsh", first put the appropriate relative directory in the remote ditrectory. */ if (machines[I].directory[1] == '\0') machines[I].rdirectory[0] = '\0'; else if (machines[I].directory[1] == '/') (void) strcpy(machines[I].rdirectory, &(machines[I].directory[2])); /* In any case, get the complete pathname for the local directory instead of "~". */ (void) strcpy(tempdir, machines[I].directory); if (tempdir[1] == '\0' || tempdir[1] == '/') { (void) strcpy(machines[I].directory, getenv("HOME")); if (tempdir[1] == '/') (void) strcat(machines[I].directory, &(tempdir[1])); } else { /* While we are doing this, if a user other than the current user is specified, check to be sure it exists. */ for (L = 1; tempdir[L] != '/' && tempdir[L] != '\0'; L++); (void) strncpy(username, &(tempdir[1]), L - 1); username[L-1] = '\0'; if ((pwbuf = getpwnam(username)) == NULL) error(0, "\tInvalid directory (%s) for %s in Dmachs, no login for %s\n", machines[I].directory, machines[I].name, username); (void) strcpy(machines[I].directory, pwbuf->pw_dir); if (tempdir[L] != '\0') (void) strcat(machines[I].directory, &(tempdir[L])); } } } break; default: if (machines[I].rsh) (void) strcpy(machines[I].rdirectory, machines[I].directory); } for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); if (temp[J] == '\0') break; } if (I == MAXMACHINES) error(0, "\tMaximum number of allowable machines exceeded in Dmachs\n"); } if ((temp = getenv("sDmachine")) == NULL) default_mach = 0; else { for (I = 0; I < nummach; I++) if (strcmp(temp, machines[I].name) == 0) { default_mach = I; break; } if (I == nummach) error(0, "\tSystem default machine (sDmachine = %s) not found in Dmachs.\n", temp); } for (I = 0; I < nummach; I++) { (void) sprintf(varname, "sD%ssuf", machines[I].name); if ((temp = getenv(varname)) != NULL) (void) strcpy(machines[I].suffix, temp); else (void) strcpy(machines[I].suffix, machines[I].name); } if ((temp = getenv("Dmachine")) != NULL) { for (I = 0; I < nummach; I++) if (strcmp(temp, machines[I].name) == 0) { default_mach = I; break; } if (I == nummach) error(0, "\tUser default machine (Dmachine = %s) not defined in system list.\n", temp); } for (I = 0; I < nummach; I++) { (void) sprintf(varname, "D%ssize", machines[I].name); if ((temp = getenv(varname)) != NULL) if ((test = strtol(temp, (char **) NULL, 0)) > 0 && test < machines[I].maxdim + 1) machines[I].dim = test; else error(0, "\tInvalid user default size (D%ssize = %d) for %s.\n", machines[I].name, test, machines[I].name); } for (I = 0; I < nummach; I++) { (void) sprintf(varname, "D%ssuf", machines[I].name); if ((temp = getenv(varname)) != NULL) (void) strcpy(machines[I].suffix, temp); } for (I = 0; I < nummach; I++) { (void) sprintf(varname, "D%sdir", machines[I].name); if ((temp = getenv(varname)) != NULL) { machines[I].lcl_here = FALSE; if (temp[0] != '/' && temp[0] != '.' && temp[0] != '~') { if (machines[I].directory[0] == '\0') (void) strcpy(machines[I].directory, temp); else { (void) strcat(machines[I].directory, "/"); (void) strcat(machines[I].directory, temp); } if (machines[I].rdirectory[0] == '\0') (void) strcpy(machines[I].rdirectory, temp); else { (void) strcat(machines[I].rdirectory, "/"); (void) strcat(machines[I].rdirectory, temp); } } else { switch (temp[0]) { case '.': if (machines[I].rcp) error(0, "\tInvalid directory (%s) for remote machine %s in %s\n", temp, machines[I].name, varname); (void) strcpy(machines[I].directory, getenv("PWD")); if (temp[1] != '\0') { if (temp[1] != '/') error(0, "\tInvalid directory (%s) for remote machine %s in %s\n", temp, machines[I].name, varname); (void) strcat(machines[I].directory, &(temp[1])); } else machines[I].lcl_here = TRUE; if (machines[I].rsh) { home = getenv("HOME"); for (J = 0; home[J] != '\0' && home[J] == machines[I].directory[J]; J++); M = 0; if (machines[I].directory[J] != '\0') for (J++; machines[I].directory[J] != '\0'; J++, M++) machines[I].rdirectory[M] = machines[I].directory[J]; machines[I].rdirectory[M] = '\0'; } break; case '~': if (machines[I].rcp) { if (temp[1] == '\0') machines[I].directory[0] = '\0'; else if (temp[1] == '/') for (J = 0; temp[J] != '\0'; J++) machines[I].directory[J] = temp[J+2]; strcpy(machines[I].rdirectory, machines[I].directory); } else { if (temp[1] == '\0') machines[I].rdirectory[0] = '\0'; else if (temp[1] == '/') (void) strcpy(machines[I].rdirectory, &(temp[2])); if (temp[1] == '\0' || temp[1] == '/') { (void) strcpy(machines[I].directory, getenv("HOME")); if (temp[1] == '/') (void) strcat(machines[I].directory, &(temp[1])); } else { for (J = 1; temp[J] != '/' && temp[J] != '\0'; J++); (void) strncpy(username, &(temp[1]), J - 1); username[J-1] = '\0'; if ((pwbuf = getpwnam(username)) == NULL) error(0, "\tInvalid directory (%s) for %s specified in %s, no login for %s\n", temp, machines[I].name, username); (void) strcpy(machines[I].directory, pwbuf->pw_dir); if (tempdir[J] != '\0') (void) strcat(machines[I].directory, &(temp[J])); } } break; } } } } for (I = 0; I < nummach; I++) { (void) sprintf(varname, "D%susr", machines[I].name); if ((temp = getenv(varname)) != NULL) { (void) strcpy(machines[I].user, temp); if (machines[I].user[0] == '~') { if (machines[I].user[1] != '\0') error(0, "\tInvalid user for %s in %s.\n", machines[I].name, varname); } else { if (machines[I].user[0] == '.') error(0, "\tInvalid user (%s) for %s in %s\n", machines[I].user, machines[I].name, varname); if (! machines[I].rsh) error(0, "\tInvalid user (%s) for %s in %s\n", machines[I].user, machines[I].name, varname); } } } cmdlnparse(argc, argv, cmdln); (void) sprintf(varname, "sD%sopt", machines[default_mach].name); if ((temp = getenv(varname)) != NULL) addbools(temp, TRUE); (void) sprintf(varname, "D%sopt", machines[default_mach].name); if ((temp = getenv(varname)) != NULL) addbools(temp, FALSE); addbools(cmdln, FALSE); if ((temp = getenv("Dinc")) != NULL) { J = 0; do { for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = J; temp[K] != ' ' && temp[K] != '\t' && temp[K] != '\n' && temp[K] != '\0'; K++); if (temp[J] != '\0') { if (NINC < MAXINCLUDE) { (void) strncpy(INCLUDE[NINC], &(temp[J]), K - J); INCLUDE[NINC][K - J] = '\0'; if (stat(INCLUDE[NINC++], &buf1) != 0) { error(0, "\tUnable to access include directory %s from Dinc\n", INCLUDE[NINC-1]); } } else { error(0, "\tMaximum number of include directories (%d) exceeded in Dinc.\n", MAXINCLUDE-1); } J = K; } } while (temp[J] != '\0'); } if ((temp = getenv("sDinc")) != NULL) { J = 0; do { for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = J; temp[K] != ' ' && temp[K] != '\t' && temp[K] != '\n' && temp[K] != '\0'; K++); if (temp[J] != '\0') { if (NINC < MAXINCLUDE) { (void) strncpy(INCLUDE[NINC], &(temp[J]), K - J); INCLUDE[NINC][K - J] = '\0'; if (stat(INCLUDE[NINC++], &buf1) != 0) { error(0, "\tUnable to access include directory %s from sDinc\n", INCLUDE[NINC-1]); } } else { error(0, "\tMaximum number of include directories (%d) exceeded in sDinc.\n", MAXINCLUDE-1); } J = K; } } while (temp[J] != '\0'); } /* If there was no quiet option, we print out the initial message. */ if (! QUIET) { (void) fprintf(stderr, "\n\n DINO %s\n", version_id); (void) fprintf(stderr, " [DIstributed Numerically Oriented language]\n"); (void) fprintf(stderr, " (Copyright, 1990, Regents of the University of Colorado)\n\n"); header = TRUE; } if (macherr) { error(2, "\tWARNING, no parallel machines defined on this system.\n\t\tOnly the first phase of the compiler will be run\n\t\tfor a basic 16 node iPSC2.\n\n"); } /* We make sure that the compiler model is set correctly. */ if (! MODEL) { if (machines[default_mach].type == 5 || machines[default_mach].type == 6) TYPE = 's'; else { if (machines[default_mach].type == 4) TYPE = 'g'; else TYPE = 'c'; } if (machines[default_mach].type == 1 || machines[default_mach].type == 5) SERIES = '1'; else SERIES = '2'; } /* We update the cube dimension and check it for correctness: */ if (! macherr) { if (CUBEDIM == 0) CUBEDIM = machines[default_mach].dim; else if (CUBEDIM < 1 || CUBEDIM > machines[default_mach].maxdim) error(0, "\tUser supplied dimension for %s (-C%d) too large.\n", machines[default_mach].name, CUBEDIM); } /* We make sure a source file was supplied. */ if (SOURCE[0] == '\0') error(1, "\tName of DINO source file was not provided.\n"); /* We extract the root of the source file. */ temp = strrchr(SOURCE, '/'); if (temp == NULL) temp = SOURCE; else temp++; temp2 = strrchr(temp, '.'); if (temp2 == NULL) test = strlen(temp); else test = temp2 - temp; (void) strncpy(ROOT, temp, test); ROOT[test] = '\0'; /* We check the user's environment to see if there is a root directory for the destination machine to which we should append any command line directory (if the command line directory starts with a "/" or a "~", then that overrides the environment directory). In addition, if the second phase is being done on the same machine as the first phase, the environment directory and commend line directories are interperted relative to the user's home directory unless that is explicitly overridden. */ if (DIRECTORY[0] != '\0') { machines[default_mach].lcl_here = FALSE; if (DIRECTORY[0] != '/' && DIRECTORY[0] != '.' && DIRECTORY[0] != '~') { if (machines[default_mach].directory[0] == '\0') (void) strcpy(machines[default_mach].directory, DIRECTORY); else { (void) strcat(machines[default_mach].directory, "/"); (void) strcat(machines[default_mach].directory, DIRECTORY); } if (machines[default_mach].rdirectory[0] == '\0') (void) strcpy(machines[default_mach].rdirectory, DIRECTORY); else { (void) strcat(machines[default_mach].rdirectory, "/"); (void) strcat(machines[default_mach].rdirectory, DIRECTORY); } } else { switch (DIRECTORY[0]) { case '.': if (machines[I].rcp) error(0, "\tInvalid directory (%s) for remote machine %s specified with \"-d\"\n", DIRECTORY, machines[default_mach].name); (void) strcpy(machines[default_mach].directory, getenv("PWD")); if (DIRECTORY[1] != '\0') { if (DIRECTORY[1] != '/') error(0, "\tInvalid directory (%s) for remote machine %s specified with \"-d\"\n", DIRECTORY, machines[default_mach].name); (void) strcat(machines[default_mach].directory, &(DIRECTORY[1])); } else machines[default_mach].lcl_here = TRUE; if (machines[default_mach].rsh) { home = getenv("HOME"); for (J = 0; home[J] != '\0' && home[J] == machines[default_mach].directory[J]; J++); K = 0; if (machines[default_mach].directory[J] != '\0') for (J++; machines[default_mach].directory[J] != '\0'; J++, K++) machines[default_mach].rdirectory[K] = machines[default_mach].directory[J]; machines[default_mach].rdirectory[K] = '\0'; } break; case '~': if (machines[default_mach].rcp) { if (DIRECTORY[1] == '\0') machines[default_mach].directory[0] = '\0'; else if (DIRECTORY[1] == '/') for (J = 0; DIRECTORY[J] != '\0'; J++) machines[default_mach].directory[J] = DIRECTORY[J+2]; strcpy(machines[default_mach].rdirectory, machines[default_mach].directory); } else { if (DIRECTORY[1] == '\0') machines[default_mach].rdirectory[0] = '\0'; else if (DIRECTORY[1] == '/') (void) strcpy(machines[default_mach].rdirectory, &(DIRECTORY[2])); if (DIRECTORY[1] == '\0' || DIRECTORY[1] == '/') { (void) strcpy(machines[default_mach].directory, getenv("HOME")); if (DIRECTORY[1] == '/') (void) strcat(machines[default_mach].directory, &(DIRECTORY[1])); } else { for (J = 1; DIRECTORY[J] != '/' && DIRECTORY[J] != '\0'; J++); (void) strncpy(username, &(DIRECTORY[1]), J - 1); username[J-1] = '\0'; if ((pwbuf = getpwnam(username)) == NULL) error(0, "\tInvalid directory (%s) for %s specified with \"-d\", no login for %s\n", DIRECTORY, machines[default_mach].name, username); (void) strcpy(machines[default_mach].directory, pwbuf->pw_dir); if (tempdir[J] != '\0') (void) strcat(machines[default_mach].directory, &(DIRECTORY[J])); } } break; } } } if (DIRECTORY[0] != '\0' && ! machines[default_mach].rcp) { mask = S_IRWXU | S_IRWXG | S_IRWXO; temp2 = DIRECTORY; do { temp2++; for (; *temp2 != '/' && *temp2 != '\0'; temp2++); (void) strncpy(tempdir, DIRECTORY, temp2 - DIRECTORY); tempdir[temp2 - DIRECTORY] = '\0'; if (stat(tempdir, &buf1) != 0) if(mkdir(tempdir, mask) != 0) { temp = getenv("HOST"); error(0, "\tUnable to create directory %s requested on %s\n", tempdir, temp); } } while (*temp2 != '\0'); } if (machines[default_mach].run == 'S') special = TRUE; switch (PARTIAL) { case 0: machines[default_mach].run = 'F'; break; case 1: machines[default_mach].run = 'P'; break; case 2: machines[default_mach].run = 'T'; break; case 3: if (machines[default_mach].run == 'F') PARTIAL = 0; else PARTIAL = 2; } if (USER[0] == '\0') { (void) strcpy(USER, machines[default_mach].user); if (machines[default_mach].user[0] == '~') { if (machines[default_mach].user[1] != '\0') error(0, "\tInvalid user for %s in %s.\n", machines[default_mach].name, varname); } else { if (machines[default_mach].user[0] == '.') error(0, "\tInvalid user (%s) for %s in %s\n", machines[default_mach].user, machines[default_mach].name, varname); if (! machines[default_mach].rsh) error(0, "\tInvalid user (%s) for %s in %s\n", machines[default_mach].user, machines[default_mach].name, varname); } } else if (! machines[default_mach].rsh && USER[0] != '~' && USER[1] != '\0') error(0, "\tInvalid user (%s) for %s specified with \"-u\" option.\n", USER, machines[default_mach].name); /* Now, we generate the output. */ /* First, we tell the shell that the command line was correct. */ (void) printf("ok\n"); /* Then we tell it what suffix model we are using. */ if (SUFFIX_MODEL && ! macherr) (void) printf("new\n"); else (void) printf("old\n"); /* Then, we generate the actual suffix. */ if (SUFFIX[0] == '\0') { if (SUFFIX_MODEL) (void) strcpy(SUFFIX, machines[default_mach].suffix); else switch (machines[default_mach].type) { case 1: (void) strcpy(SUFFIX, "D1"); break; case 2: (void) strcpy(SUFFIX, "D2"); break; case 3: (void) strcpy(SUFFIX, "D8"); break; case 4: (void) strcpy(SUFFIX, "G"); break; case 5: (void) strcpy(SUFFIX, "S1"); break; case 6: (void) strcpy(SUFFIX, "S2"); break; } } (void) printf("%s\n", SUFFIX); /* Then we give it the name of the source file. */ (void) printf("%s\n", SOURCE); /* Then we generate a string with all the include directories in it. */ for (I = 0; I < NINC; I++) { (void) printf("-I%s", INCLUDE[I]); if (I < NINC - 1) (void) printf(" "); } if (NINC == 0) (void) printf(" "); (void) printf("\n"); /* Next, we generate a string with all the compiler options in it. */ used = FALSE; if (BUFSIZE > 0) { if (used) (void) printf(" "); (void) printf("-B%d", BUFSIZE); used = TRUE; } if (FIRSTTYPE > 0) { if (used) (void) printf(" "); (void) printf("-S%d", FIRSTTYPE); used = TRUE; } if (LASTTYPE > 0) { if (used) (void) printf(" "); (void) printf("-L%d", LASTTYPE); used = TRUE; } if (used) (void) printf(" "); (void) printf("-M%c%c ", TYPE, SERIES); (void) printf("-C%d\n", CUBEDIM); /* Next, we generate a string with all the formatter options in it. */ used = FALSE; if (ALADIN) { (void) printf("-a"); used = TRUE; } if (WARNINGS) { if (used) (void) printf(" "); (void) printf("-w"); used = TRUE; } if (COMMENTS) { if (used) (void) printf(" "); (void) printf("-c"); used = TRUE; } if (NOTES) { if (used) (void) printf(" "); (void) printf("-n"); used = TRUE; } if (NUMBERS) { if (used) (void) printf(" "); (void) printf("-l"); used = TRUE; } if (ORDER) { if (used) (void) printf(" "); (void) printf("-e"); used = TRUE; } if (! used) (void) printf(" "); (void) printf("\n"); /* Next, we generate a string with all the splitter options in it. */ if (! SUFFIX_MODEL) (void) printf("-o "); (void) printf("-s%s\n", SUFFIX); /* Next, we generate the name of the target machine. */ if (macherr) (void) printf(" \n"); else (void) printf("%s\n", machines[default_mach].name); /* Then, we generate the root name of the source file. */ (void) printf("%s\n", ROOT); /* Next, we generate the copy command that should be used (note there are two parts). */ if (machines[default_mach].run == 'T' || machines[default_mach].run == 'P') { if (machines[default_mach].rcp) { (void) strcpy(OUTLINE, "rcp"); if (machines[default_mach].date) (void) strcat(OUTLINE, " -p"); } else { if (machines[default_mach].lcl_here) (void) strcpy(OUTLINE, " "); else (void) strcpy(OUTLINE, "cp -p"); } } else (void) strcpy(OUTLINE, " "); (void) printf("%s\n", OUTLINE); if (machines[default_mach].run == 'T' || machines[default_mach].run == 'P') { if (machines[default_mach].rcp) { if (USER[0] != '~' || USER[1] != '\0') { (void) strcpy(OUTLINE, USER); (void) strcat(OUTLINE, "@"); } else OUTLINE[0] = '\0'; (void) strcat(OUTLINE, machines[default_mach].address); (void) strcat(OUTLINE, ":"); (void) strcat(OUTLINE, machines[default_mach].rdirectory); } else { if (machines[default_mach].lcl_here) { (void) strcpy(OUTLINE, " "); } else { (void) strcpy(OUTLINE, machines[default_mach].directory); } } } else (void) strcpy(OUTLINE, " "); (void) printf("%s\n", OUTLINE); /* Next, we generate the execute command that should be used. */ if (machines[default_mach].run == 'T') { if (machines[default_mach].rsh) { (void) strcpy(OUTLINE, "rsh "); (void) strcat(OUTLINE, machines[default_mach].address); (void) strcat(OUTLINE, " "); if (USER[0] != '~' || USER[1] != '\0') { (void) strcat(OUTLINE, "-l "); (void) strcat(OUTLINE, USER); (void) strcat(OUTLINE, " "); } if (machines[default_mach].rdirectory[0] != '\0') { (void) strcat(OUTLINE, "cd "); (void) strcat(OUTLINE, machines[default_mach].rdirectory); (void) strcat(OUTLINE, "; "); } (void) strcat(OUTLINE, "dino2 "); if (QUIET) (void) strcat(OUTLINE, "T "); else (void) strcat(OUTLINE, "F "); (void) strcat(OUTLINE, machines[default_mach].name); if (SUFFIX_MODEL) (void) strcat(OUTLINE, " new "); else (void) strcat(OUTLINE, " old "); (void) strcat(OUTLINE, SUFFIX); } else { (void) strcpy(OUTLINE, "dino2 "); if (QUIET) (void) strcat(OUTLINE, "T "); else (void) strcat(OUTLINE, "F "); (void) strcat(OUTLINE, machines[default_mach].name); if (SUFFIX_MODEL) (void) strcat(OUTLINE, " new "); else (void) strcat(OUTLINE, " old "); (void) strcat(OUTLINE, SUFFIX); } } else (void) strcpy(OUTLINE, " "); (void) printf("%s\n", OUTLINE); /* Then we generate a change directory command if we need it for the local machine. */ if (machines[default_mach].run == 'T' && ! machines[default_mach].rsh && ! machines[default_mach].lcl_here) { (void) strcpy(OUTLINE, "cd "); (void) strcat(OUTLINE, machines[default_mach].directory); } else (void) strcpy(OUTLINE, " "); (void) printf("%s\n", OUTLINE); /* Next, we generate the create directory command that should be used. */ if ((machines[default_mach].run == 'T' || machines[default_mach].run == 'P') && machines[default_mach].rdirectory[0] != '\0') { if (machines[default_mach].rcp) { (void) strcpy(OUTLINE, "rsh "); (void) strcat(OUTLINE, machines[default_mach].address); if (USER[0] != '~' || USER[1] != '\0') { (void) strcat(OUTLINE, " -l "); (void) strcat(OUTLINE, USER); } (void) strcat(OUTLINE, " dinocrdr "); (void) strcat(OUTLINE, machines[default_mach].rdirectory); } else { (void) strcpy(OUTLINE, " "); } } else (void) strcpy(OUTLINE, " "); (void) printf("%s\n", OUTLINE); /* Next, we generate a string with the local directory in it. */ if (machines[default_mach].directory[0] != '\0') (void) printf("%s\n", machines[default_mach].directory); else (void) printf(" \n"); /* Then, we generate a string with the user name in it. */ if (USER[0] != '\0') (void) printf("%s\n", USER); else (void) printf(" \n"); /* Next, we generate a string with the machine address in it. */ if (macherr) (void) printf(" \n"); else (void) printf("%s\n", machines[default_mach].address); /* Then, we generate the quiet flag. */ (void) printf("%s\n", QUIET?"T":"F"); /* Next, we generate the partial flag. */ (void) printf("%d\n", PARTIAL); /* Then, we generate the rcp flag. */ if (machines[default_mach].lcl_here) (void) printf("%s\n", "N"); else (void) printf("%s\n", machines[default_mach].rcp?"R":"L"); /* Next, we generate the rsh flag. */ (void) printf("%s\n", machines[default_mach].rsh?"T":"F"); /* Finally, we generate the special flag. */ (void) printf("%s\n", special?"T":"F"); return(0); } /*VARARGS*/ static void error(va_alist) va_dcl { va_list ap; char *fmt; int type; static BOOL first = TRUE; if (! header && ! QUIET) { (void) fprintf(stderr, "\n\n DINO %s\n", version_id); (void) fprintf(stderr, " [DIstributed Numerically Oriented language]\n"); (void) fprintf(stderr, " (Copyright, 1990, Regents of the University of Colorado)\n\n"); header = TRUE; } if (first) { (void) fprintf(stderr, "\n"); first = FALSE; } va_start(ap); type = va_arg(ap, int); fmt = va_arg(ap, char *); (void) _doprnt(fmt, ap, stderr); va_end(ap); (void) fprintf(stderr, "\n"); if (type == 1) sh_message(); if (type < 2) { (void) printf("doa"); exit(1); } } static void sh_message() { if (! header && ! QUIET) { (void) fprintf(stderr, "\n\n DINO %s\n", version_id); (void) fprintf(stderr, " [DIstributed Numerically Oriented language]\n"); (void) fprintf(stderr, " (Copyright, 1990, Regents of the University of Colorado)\n\n"); } (void) fprintf(stderr, "Usage: dino [-<machine name>] [-w] [-c] [-n] [-l] [-e] [-o] [-p] [-D]\n"); (void) fprintf(stderr, " [-P] [-Q] [-h[elp]] [-s <suffix>] [-C <num>] [-d <directory>]\n"); (void) fprintf(stderr, " [-u <user>] [-I <directory>] <file>\n\n"); } static void message() { sh_message(); (void) fprintf(stderr, "Where:\n"); (void) fprintf(stderr, " <machine name> - generates code for this parallel machine\n"); (void) fprintf(stderr, " w - does not print compiler warnings\n"); (void) fprintf(stderr, " c - prints compiler comments\n"); (void) fprintf(stderr, " n - prints compiler notes\n"); (void) fprintf(stderr, " f - prints entire source listing\n"); (void) fprintf(stderr, " l - numbers the lines in the listing\n"); (void) fprintf(stderr, " e - print errors in the order they come out of compiler\n"); (void) fprintf(stderr, " o - uses the old style model for building suffixes\n"); (void) fprintf(stderr, " p - stops after the C files are copied to the parallel machine\n"); (void) fprintf(stderr, " D - prints out all the current system defaults\n"); (void) fprintf(stderr, " P - stops after the C files are generated\n"); (void) fprintf(stderr, " Q - only prints out error messages\n"); (void) fprintf(stderr, " h[elp] - prints this message\n"); (void) fprintf(stderr, " s <suffix> - appends <suffix> to the names of the generated C files\n"); (void) fprintf(stderr, " C <num> - set cube dimension to <num>\n"); (void) fprintf(stderr, " d <directory> - uses <directory> to do the work on the parallel machine\n"); (void) fprintf(stderr, " u <user> - set the user on the parallel machine to <user>\n"); (void) fprintf(stderr, " I <directory> - look for include files in <directory>\n (more than one \"-I <directory>\" can be used)\n"); (void) fprintf(stderr, " <file> - name of the DINO file to be compiled\n\n"); (void) fprintf(stderr, " Any of the on/off options can be turned off by preceeding it\n with a \"^\", for example, \"-^w\"\n\n"); } static void dmessage() { message(); (void) fprintf(stderr, "The following additional options are supported for diagnostic purposes --\n"); (void) fprintf(stderr, " [-a] [-H[ELP]] [-B <num>] [-S <num>] [-L <num>] [-M<let><num>]\n\n"); (void) fprintf(stderr, "Where:\n"); (void) fprintf(stderr, " a - prints aladin line numbers for errors\n"); (void) fprintf(stderr, " H[ELP] - prints this message\n"); (void) fprintf(stderr, " B <num> - sets buffer size to <num>\n"); (void) fprintf(stderr, " S <num> - set first message type to <num>\n"); (void) fprintf(stderr, " L <num> - set last message type to <num>\n"); (void) fprintf(stderr, " M<let><num> - set machine model to M<let><num> where:\n"); (void) fprintf(stderr, " <let> = s (simulator), c (cube), or g (grail) and\n"); (void) fprintf(stderr, " <num> = 1 (ipsc1) or 2 (ipsc2 or i860))\n\n"); } static void cmdlnparse(argc, argv, output) int argc; char *argv[]; char *output; { int I, J, K; int count = 0; BOOL bingo; char option[LINESIZE]; char *temp, *temp2; char varname[MAXMACHNAME + 6]; char tempdir[MAXPATHLEN]; char holder[MAXPATHLEN]; char name[MAXMACHNAME]; char user[NAMESIZE]; char username[25]; struct passwd *pwbuf; struct stat buf1; BOOL found = FALSE; BOOL current; BOOL explicit = FALSE; if (argc < 2) { message(); (void) printf("doa"); exit(1); } for (I = 1; I < argc; I++) { if (argv[I][0] == '-') { bingo = FALSE; for (J = 0; J < nummach; J++) { if (strcmp(&(argv[I][1]), machines[J].name) == 0) { if (explicit) error(1, "\tMultiple machine names (%s, %s) specified on command line.\n", machines[default_mach].name, machines[J].name); default_mach = J; bingo = TRUE; explicit = TRUE; break; } } if (bingo) continue; if (argv[I][1] == '^') { output[count++] = '^'; for (J = 0; argv[I][J] != '\0'; J++) option[J] = argv[I][J+1]; } else (void) strcpy(option, argv[I]); switch (option[1]) { case 'a': if (option[2] == '\0') output[count++] = 'a'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'c': if (option[2] == '\0') output[count++] = 'c'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'd': if (option[2] == '\0') { if (I + 1 < argc && argv[I+1][0] != '-') { (void) strcpy(DIRECTORY, &(argv[I+1][0])); I++; } else error(0, "\tMissing argument to DINO option: %s\n", argv[I]); } else (void) strcpy(DIRECTORY, &(option[2])); break; case 'e': if (option[2] == '\0') output[count++] = 'e'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'h': if (option[2] == '\0' || (strcmp(&(option[1]), "help") == 0)) { message(); (void) printf("quit"); exit(0); } else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'l': if (option[2] == '\0') output[count++] = 'l'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'n': if (option[2] == '\0') output[count++] = 'n'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'o': if (option[2] == '\0') output[count++] = 'o'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'p': if (option[2] == '\0') output[count++] = 'p'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 's': if (option[2] == '\0') { if (I + 1 < argc && argv[I+1][0] != '-') { (void) strcpy(SUFFIX, &(argv[I+1][0])); I++; } else error(0, "\tMissing argument to DINO option: %s\n", argv[I]); } else (void) strcpy(SUFFIX, &(option[2])); break; case 'u': if (option[2] == '\0') { if (I + 1 < argc && argv[I+1][0] != '-') { (void) strcpy(USER, &(argv[I+1][0])); I++; } else error(0, "\tMissing argument to DINO option: %s\n", argv[I]); } else (void) strcpy(USER, &(option[2])); break; case 'w': if (option[2] == '\0') output[count++] = 'w'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'B': if (option[2] == '\0') { if (I + 1 >= argc || argv[I+1][0] == '-' || (BUFSIZE = strtol(argv[I+1], &temp, 0)) == 0 || temp[0] != '\0') { if (I + 1 >= argc || argv[I+1][0] == '-') error(0, "\tMissing argument to DINO option: %s\n", argv[I]); else error(0, "\tInvalid argument to DINO option: %s %s\n", argv[I], argv[I+1]); } } else if ((BUFSIZE = strtol(&(option[2]), &temp, 0)) == 0 || temp[0] != '\0') error(0, "\tInvalid argument to DINO option: %s\n", argv[I]); break; case 'C': if (option[2] == '\0') { if (I + 1 >= argc || argv[I+1][0] == '-' || (CUBEDIM = strtol(argv[I+1], &temp, 0)) == 0 || temp[0] != '\0') { if (I + 1 >= argc || argv[I+1][0] == '-') error(0, "\tMissing argument to DINO option: %s\n", argv[I]); else error(0, "\tInvalid argument to DINO option: %s %s\n", argv[I], argv[I+1]); } I++; } else if ((CUBEDIM = strtol(&(option[2]), &temp, 0)) == 0 || temp[0] != '\0') error(0, "\tInvalid argument to DINO option: %s\n", argv[I]); break; case 'D': if (option[2] != '\0') { error(0, "\tNon-existent DINO option: %s\n", argv[I]); } if (I + 1 < argc && argv[I+1][0] != '-') { error(0, "\tNon-existent DINO option: %s %s\n", argv[I], argv[I+1]); } if (! QUIET) { (void) fprintf(stderr, "\n\n DINO\n"); (void) fprintf(stderr, " [DIstributed Numerically Oriented language]\n"); (void) fprintf(stderr, " (Copyright, 1990, Regents of the University of Colorado)\n\n"); } else (void) fprintf(stderr,"\n"); if ((temp = getenv("Dmachs")) == NULL) { (void) fprintf(stderr, "\tNo parallel machines defined on this system.\n\n"); (void) printf("quit\n"); exit(0); } if (temp[0] == '\0') { (void) fprintf(stderr, "\tNo parallel machines defined on this system.\n\n"); (void) printf("quit\n"); exit(0); } if ((temp2 = getenv("sDmachine")) == NULL) default_mach = 0; else { for (I = 0; I < nummach; I++) if (strcmp(temp2, machines[I].name) == 0) { default_mach = I; break; } } (void) fprintf(stderr, " The following machines and defaults are defined by the system:\n"); J = 0; for (I = 0; I < MAXMACHINES; I++) { for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); if (temp[J] == '\0') break; for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) name[K] = temp[J]; name[K] = '\0'; (void) fprintf(stderr, "\n %s -->\n", name); for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) holder[K] = temp[J]; holder[K] = '\0'; if (holder[0] == '.') (void) fprintf(stderr, " the current machine will be used as the target\n"); else (void) fprintf(stderr, " the address of the target machine is %s\n", holder); for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) user[K] = temp[J]; user[K] = '\0'; current = FALSE; if (user[0] == '~') { temp2 = getenv("USER"); (void) strcpy(user, temp2); current = TRUE; } (void) fprintf(stderr, " the target user is %s", user); if (current) (void) fprintf(stderr, " (the current user)\n"); else (void) fprintf(stderr, "\n"); for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); for (K = 0; temp[J] != ' ' && temp[J] != '\0' && temp[J] != '\t' && temp[J] != '\n'; J++, K++) holder[K] = temp[J]; holder[K] = '\0'; current = FALSE; switch (holder[0]) { case '.': (void) strcpy(tempdir, holder); (void) strcpy(holder, getenv("PWD")); if (tempdir[1] != '\0') (void) strcat(holder, &(tempdir[1])); current = TRUE; break; case '~': if (machines[I].rcp) { if (holder[1] == '\0') holder[0] = '\0'; else if (holder[1] == '/') for (J = 0; holder[J] != '\0'; J++) holder[J] = holder[J+2]; } else { (void) strcpy(tempdir, holder); if (tempdir[1] == '\0' || tempdir[1] == '/') { (void) strcpy(holder, getenv("HOME")); if (tempdir[1] == '/') (void) strcat(holder, &(tempdir[1])); } else { for (J = 1; tempdir[J] != '/' && tempdir[J] != '\0'; J++); (void) strncpy(username, &(tempdir[1]), J - 1); username[J-1] = '\0'; pwbuf = getpwnam(username); (void) strcpy(holder, pwbuf->pw_dir); if (tempdir[J] != '\0') (void) strcat(holder, &(tempdir[J])); } } break; } if (strlen(holder) > 0) { if (machines[I].rcp) (void) fprintf(stderr, " the destination directory is\n ~%s/%s\n on %s\n", user, holder, name); else { (void) fprintf(stderr, " the destination directory is\n %s\n on this machine\n", holder); if (current) (void) fprintf(stderr, " (directory is relative to current directory)\n"); } } else (void) fprintf(stderr, " the destination directory is ~%s on %s\n", user, name); for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++); (void) fprintf(stderr, " the target machine is "); switch (temp[J++]) { case 's' : (void) fprintf(stderr, "an iPSC1 simulator\n"); break; case 'S' : (void) fprintf(stderr, "an iPSC2 simulator\n"); break; case '1' : (void) fprintf(stderr, "an iPSC1\n"); break; case '2' : (void) fprintf(stderr, "an iPSC2\n"); break; case '8' : (void) fprintf(stderr, "an i860 version of the iPSC2\n"); break; case 'G' : (void) fprintf(stderr, "a distributed sun machine\n"); break; } (void) fprintf(stderr, " largest allowable dimension is %d.\n", (int) strtol(&(temp[J++]), (char **) NULL, 0)); for (; isdigit(temp[J]); J++); J += 4; switch (machines[I].run) { case 'T': if (machines[I].rcp) { if (machines[I].rsh) { if (machines[I].date) { (void) fprintf(stderr, " intermediate files will be copied to %s and\n", name); (void) fprintf(stderr, " compiled there for any file that has been changed\n"); } else { (void) fprintf(stderr, " intermediate files will be copied to %s and \n", name); (void) fprintf(stderr, " compiled there (DINO is not able to check dates)\n"); } } else { (void) fprintf(stderr, " intermediate files will be copied to %s\n", name); } } else { if (machines[I].rsh) { (void) fprintf(stderr, " intermediate files will be copied to the destination directory\n"); (void) fprintf(stderr, " and compiled there if they have been changed\n"); } else { (void) fprintf(stderr, " intermediate files will be copied to the destination directory"); (void) fprintf(stderr, " but not compiled\n"); } } break; case 'F': (void) fprintf(stderr, " only the intermediate files will be generated\n"); break; case 'S': (void) fprintf(stderr, " there is custom code for compilation on this machine\n"); (void) fprintf(stderr, " see the \"dino.special\" shell script to examine it\n"); break; } (void) fprintf(stderr, " the default dimension is %d.\n", (int) strtol(&(temp[J++]), (char **) NULL, 0)); for (; isdigit(temp[J]); J++); (void) sprintf(varname, "sD%sopt", name); if ((temp2 = getenv(varname)) != NULL) { for (K = 0; temp2[K] != '\0'; K++) { if (temp2[K] == '!') continue; switch (temp2[K]) { case 'a': (void) fprintf(stderr, " ALADIN line numbers will be printed\n"); break; case 'c': (void) fprintf(stderr, " DINO compiler comments will be printed\n"); break; case 'e': (void) fprintf(stderr, " DINO will print errors in the order it detects them\n"); break; case 'l': (void) fprintf(stderr, " DINO number the lines of the program listing\n"); break; case 'n': (void) fprintf(stderr, " DINO compiler notes will be printed\n"); break; case 'o': (void) fprintf(stderr, " DINO will use the old suffix model\n"); break; case 'w': (void) fprintf(stderr, " DINO compiler warnings will not be printed\n"); break; case 'Q': (void) fprintf(stderr, " DINO will run in quiet mode\n"); break; } } } } (void) fprintf(stderr, "\n The system default machine is %s\n\n", machines[default_mach].name); (void) printf("quit\n"); exit(0); break; case 'H': if (option[2] == '\0' || (strcmp(&(option[1]), "HELP") == 0)) { dmessage(); (void) printf("quit"); exit(0); } else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'I': if (option[2] == '\0') { if (I + 1 < argc && argv[I+1][0] != '-') { if (stat(argv[I+1], &buf1) != 0) { error(0, "\tUnable to access include directory %s\n", argv[I+1]); } else { if (NINC < MAXINCLUDE) { (void) strcpy(INCLUDE[NINC++], argv[I+1]); I++; } else error(0, "\tMaximun number of include directories (%d) exceeded.\n", MAXINCLUDE-1); } } else { error(0, "\tMissing argument to DINO option: %s\n", argv[I]); } } else { if (stat(&(option[2]), &buf1) != 0) { error(0, "\tUnable to access include directory %s\n", &(argv[I][2])); } else { if (NINC < MAXINCLUDE) (void) strcpy(INCLUDE[NINC++], &(argv[I][2])); else error(0, "\tMaximun number of include directories (%d) exceeded.\n", MAXINCLUDE-1); } } break; case 'L': if (option[2] == '\0') { if (I + 1 >= argc || argv[I+1][0] == '-' || (LASTTYPE = strtol(argv[I+1], &temp, 0)) == 0 || temp[0] != '\0') { if (I + 1 >= argc || argv[I+1][0] == '-') error(0, "\tMissing argument to DINO option: %s\n", argv[I]); else error(0, "\tInvalid argument to DINO option: %s %s\n", argv[I], argv[I+1]); } } else if ((LASTTYPE = strtol(&(option[2]), &temp, 0)) == 0 || temp[0] != '\0') error(0, "\tInvalid argument to DINO option: %s\n", argv[I]); break; case 'M': MODEL = TRUE; if (option[2] == '\0') { if (I + 1 < argc && argv[I+1][0] != '-') { switch (argv[I+1][0]) { case 's': TYPE = 's'; break; case 'c': TYPE = 'c'; break; default: error(0, "\tIncorrect argument to DINO Model option: %s %s\n", argv[I], argv[I+1]); } if (argv[I+1][1] == '\0') { if (I + 2 < argc && argv[I+2][0] != '-') { switch (argv[I+1][1]) { case '1': SERIES = '1'; break; case '2': SERIES = '2'; break; default: error(0, "\tIncorrect argument to DINO Model option: %s %s\n", argv[I], argv[I+1]); } } else error(0, "\tMissing argument to DINO option: %s\n", argv[I]); if (argv[I+1][2] != '\0') error(0, "\tIncorrect argument to DINO Model option: %s %s\n", argv[I], argv[I+1]); I++; } else { switch (argv[I+1][1]) { case '1': SERIES = '1'; break; case '2': SERIES = '2'; break; default: error(0, "\tIncorrect argument to DINO Model option: %s %s\n", argv[I], argv[I+1]); } if (argv[I+1][2] != '\0') error(0, "\tIncorrect argument to DINO Model option: %s %s\n", argv[I], argv[I+1]); } } else error(0, "\tMissing argument to DINO Model option: %s\n", argv[I]); I++; } else { switch (option[2]) { case 's': TYPE = 's'; break; case 'c': TYPE = 'c'; break; default: error(0, "\tIncorrect argument to DINO Model option: %s\n", argv[I]); } if (option[3] == '\0') { if (I + 1 < argc && argv[I+1][0] != '-') { switch (argv[I+1][1]) { case '1': SERIES = '1'; break; case '2': SERIES = '2'; break; default: error(0, "\tIncorrect argument to DINO Model option: %s %s\n", argv[I], argv[I+1]); } I++; } else error(0, "\tMissing argument to DINO Model option: %s\n", argv[I]); } else { switch (option[3]) { case '1': SERIES = '1'; break; case '2': SERIES = '2'; break; default: error(0, "\tIncorrect argument to DINO Model option: %s\n", argv[I]); } if (option[4] != '\0') error(0, "\tIncorrect argument to DINO Model option: %s\n", argv[I]); } } break; case 'P': if (option[2] == '\0') output[count++] = 'P'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'Q': if (option[2] == '\0') output[count++] = 'Q'; else error(1, "\tNon-existent DINO option: %s\n", argv[I]); break; case 'S': if (option[2] == '\0') { if (I + 1 >= argc || argv[I+1][0] == '-' || (FIRSTTYPE = strtol(argv[I+1], &temp, 0)) == 0 || temp[0] != '\0') { if (I + 1 >= argc || argv[I+1][0] == '-') error(0, "\tMissing argument to DINO option: %s\n", argv[I]); else error(0, "\tInvalid argument to DINO option: %s %s\n", argv[I], argv[I+1]); } } else if ((FIRSTTYPE = strtol(&(option[2]), &temp, 0)) == 0 || temp[0] != '\0') error(0, "\tInvalid argument to DINO option: %s\n", argv[I]); break; default: if (! macherr) error(1, "\tNon-existent DINO option: %s\n", argv[I]); else error(2, "\tUnknown DINO option: %s. Continuing anyway.\n", argv[I]); } } else { if (found) { error(0, "\tMore than one DINO source file specified:\n\t\t%s\n\t\t%s\n", SOURCE, argv[I]); } else { if (stat(argv[I], &buf1) != 0) error(0, "\tUnable to access DINO source file %s.\n", argv[I]); else { (void) strcpy(SOURCE, argv[I]); found = TRUE; } } } } } static void addbools(input, shell) char *input; BOOL shell; { int I; BOOL value = TRUE; for (I = 0; input[I] != '\0'; I++) { if (input[I] == '^') { value = FALSE; continue; } switch (input[I]) { case 'a': ALADIN = value; break; case 'c': COMMENTS = value; break; case 'e': ORDER = value; break; case 'l': NUMBERS = value; break; case 'n': NOTES = value; break; case 'o': SUFFIX_MODEL = ! value; break; case 'p': if (shell) { error(0, "\tInvalid option \"p\" in sD%sopt\n", machines[default_mach].name); } else { if (value) PARTIAL = 1; else PARTIAL = 2; } break; case 'w': WARNINGS = value; break; case 'P': if (shell) { error(0, "\tInvalid option \"P\" in sD%sopt\n", machines[default_mach].name); } else { if (value) PARTIAL = 0; else PARTIAL = 2; } break; case 'Q': QUIET = value; break; default: if (shell) error(0, "\tInvalid system option \"%c\" provided in sD%sopt\n", input[I], machines[default_mach].name); else error(0, "\tInvalid user option \"%c\" provided in D%sopt\n", input[I], machines[default_mach].name); } value = TRUE; } }